<template>
  <div>
    <quill-editor
      v-model:content="content"
      :options="editorOptions"
      contentType="html"
      ref="myQuillEditorRef"
      @text-change="onTextChange"
      @ready="onEditorReady"
      :style="{ height: '300px' }"
    ></quill-editor>

    <!-- 自定义插入超链接的弹框 -->
    <modal-dialog
      :width="700"
      :visible="visible"
      title="插入超链接"
      :footerType="1"
      okText="确认"
      cancelText="取消"
      @ok="hdlOk"
      @cancel="hdlCancel"
    >
      <div class="link_url">
        <span>链接地址：</span>
        <a-input v-model:value="linkUrl" placeholder="请输入链接地址" />
      </div>
    </modal-dialog>
  </div>
</template>

<script lang="ts">
import { upload } from "@/service/api/file";
import { Quill, QuillEditor } from "@vueup/vue-quill";
import "@vueup/vue-quill/dist/vue-quill.snow.css";

export default defineComponent({
  components: {
    QuillEditor,
  },
  props: {
    // 最长内容字符
    maxLength: {
      type: Number,
      default: null,
    },
    // 是否为签到活动管理
    isSignPlaceholder: {
      type: Boolean,
      default: false,
    },
    // 禁用/启用富文本框
    isEditorDisabled: {
      type: Boolean,
      default: false,
    },
    // 签到活动管理 - dialog框类型
    signActiveType: {
      type: String,
      default: "",
    },
  },
  setup(props: any) {
    const { proxy }: any = getCurrentInstance();
    let content = ref<string>("");
    const fontSize = Array.from(
      { length: 16 },
      (_, index) => `${35 + index}px`
    );

    onMounted(() => {
      const SizeAttributor = Quill.import("attributors/style/size");
      SizeAttributor.whitelist = fontSize;
      Quill.register(SizeAttributor, true);
    });

    let editorOptions = ref<object>({
      modules: {
        toolbar: [
          ["bold", "italic"],
          [{ size: fontSize }],
          [{ color: [] }],
          ["link"],
          ["image"],
        ],
      },

      placeholder: "请输入正文...",
      theme: "snow",
      readOnly: props.isEditorDisabled,
    });

    watch(
      () => props.isEditorDisabled,
      (newVal) => {
        if (quillInstance) {
          quillInstance.enable(!newVal);
        }
      }
    );

    watch(
      () => props.signActiveType,
      (newVal) => {
        // console.log('newVal', newVal)
        nextTick(() => {
          const quillContainer = quillInstance.container;
          // console.log('quillContainer', quillContainer)

          const placeholder =
            quillContainer.querySelector("[data-placeholder]");
          // console.log('placeholder', placeholder)

          if (placeholder && newVal == "view") {
            // placeholder.style.display = 'none'
            placeholder.setAttribute("data-placeholder", "");
          } else {
            if (props.isSignPlaceholder == true) {
              placeholder.setAttribute(
                "data-placeholder",
                "请输入活动说明文本，300个字以内"
              );
            } else {
              placeholder.setAttribute("data-placeholder", "请输入正文...");
            }
          }
        });
      },
      {
        immediate: true,
        deep: true,
      }
    );

    let quillInstance: Quill | null = null;
    let textLength = ref<number>(0);

    const onTextChange = (delta: any, oldDelta: any, source: string) => {
      if (source === "user") {
        // 清除默认样式
        // quillInstance.format('clean')
        // 立即设置字体颜色和大小
        setFontFormat();
      }
      // 获取当前文本长度
      const currentLength = quillInstance.getLength();
      textLength.value = currentLength;
      // console.log('currentLength', currentLength)
      const maxLength = props.maxLength ? props.maxLength : 3000;
      // 如果超过最大长度，撤销最后的操作以保持长度不变
      if (currentLength > maxLength) {
        quillInstance.history.undo();
      }

      quillInstance.root.addEventListener("keydown", handleKeyDown);
    };

    /**阻止默认事件 */
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Enter") {
        event.preventDefault();
        event.stopPropagation();
      }
    };

    const setFontFormat = () => {
      const selection = quillInstance?.getSelection();
      // console.log('selection', selection)

      if (selection) {
        const formats = quillInstance?.getFormat(
          selection.index,
          selection.length
        );
        const color = formats.color || "rgb(0,0,0)";
        const size = formats.size || "35px";

        const bold = formats.bold || false;
        const italic = formats.italic || false;

        // 设置字体颜色和大小
        quillInstance.format("color", color);
        quillInstance.format("size", size);

        quillInstance.format("bold", bold);
        quillInstance.format("italic", italic);

        // 移除现有样式
        quillInstance.removeFormat(selection.index, selection.length);
      }
    };

    /* ************************************************************************************************* */
    let visible = ref<boolean>(false);
    let linkUrl = ref<string>("");
    const hdlOk = () => {
      visible.value = false;
      quillInstance.format("link", linkUrl.value);
    };
    const hdlCancel = () => {
      visible.value = false;
    };

    /* ************************************************************************************************* */
    const onEditorReady = (editor: Quill) => {
      quillInstance = editor;
      quillInstance.enable(!props.isEditorDisabled);

      const defaultFontSize = "35px";
      quillInstance.root.style.fontSize = defaultFontSize;

      // 自定义图片上传
      editor.getModule("toolbar").addHandler("image", () => {
        const input = document.createElement("input");
        input.setAttribute("type", "file");
        input.setAttribute("accept", "image/*");
        input.click();

        input.addEventListener("change", () => {
          // quillInstance.format('clean')

          const file = input.files?.[0];
          if (file) {
            const allowedExtensions = ["jpg", "jpeg", "png"];
            const fileExtension = file.name.split(".").pop().toLowerCase();
            const maxSizeInBytes = 500 * 1024; // 500 KB

            if (
              allowedExtensions.includes(fileExtension) &&
              file.size <= maxSizeInBytes
            ) {
              let formData = new FormData();
              formData.append("file", file);
              formData.append("isPrivate", "false");

              let headers = {
                ["Content-Type"]: "multipart/form-data",
              };

              upload(formData, headers).then((res: any) => {
                if (res.data.getURL) {
                  const range = quillInstance.getSelection();
                  quillInstance.insertEmbed(
                    range.index,
                    "image",
                    res.data.getURL,
                    Quill.sources.USER
                  );
                  quillInstance.setSelection(
                    range.index + 1,
                    Quill.sources.USER
                  );
                }
              });
            } else {
              if (!allowedExtensions.includes(fileExtension)) {
                proxy.$message.error("仅支持jpg、png的图片");
              } else {
                proxy.$message.error("图片最大不超过500k");
              }
            }
          }
        });
      });

      const fontSizeDropdown = quillInstance.container.querySelector(
        ".ql-size .ql-picker-label"
      );
      if (fontSizeDropdown) {
        fontSizeDropdown.addEventListener("click", () => {
          const defaultSize = "35px";
          quillInstance.format("size", defaultSize);
        });
      }

      // 超链接
      const linkHandler = () => {
        linkUrl.value = "";
        visible.value = true;
      };
      const toolbar = quillInstance.getModule("toolbar");
      toolbar.addHandler("link", linkHandler);
    };

    /**使用 watchEffect 监听 content 的变化 */
    watchEffect(() => {
      // 设置 Quill 内容为 content 的值
      if (quillInstance) {
        const currentContent = quillInstance.getText();

        if (currentContent !== content.value) {
          // 清空 Quill 内容，然后设置新的内容
          quillInstance.setText("");
          quillInstance.clipboard.dangerouslyPasteHTML(
            0,
            content.value,
            "user"
          );
          onTextChange(null, null, "user");
        }
      }
    });

    // 清空富文本框
    const clearFormat = () => {
      if (quillInstance) {
        quillInstance.setText("");
        content.value = "";

        const defaultFontSize = "35px";
        quillInstance.format("size", defaultFontSize);
      }
    };

    return {
      content,
      editorOptions,
      textLength,
      onEditorReady,
      onTextChange,
      clearFormat,

      visible,
      linkUrl,
      hdlOk,
      hdlCancel,
    };
  },
});
</script>

<style lang="less">
.ql-snow .ql-picker.ql-size {
  width: 70px;
}

.generate-font-size-styles() {
  @fontSizeStart: 35;
  @fontSizeEnd: 50;
  @fontSizeStep: 1;

  .ql-snow
    .ql-picker.ql-size
    .ql-picker-label[data-value="@{fontSizeStart}px"]::before,
  .ql-snow
    .ql-picker.ql-size
    .ql-picker-item[data-value="@{fontSizeStart}px"]::before {
    content: "@{fontSizeStart}px";
  }
  .generate-font-size-styles-loop(@fontSize: @fontSizeStart)
    when
    (@fontSize <= @fontSizeEnd) {
    .ql-snow
      .ql-picker.ql-size
      .ql-picker-label[data-value="@{fontSize}px"]::before,
    .ql-snow
      .ql-picker.ql-size
      .ql-picker-item[data-value="@{fontSize}px"]::before {
      content: "@{fontSize}px";
    }
    .generate-font-size-styles-loop(@fontSize + @fontSizeStep);
  }
  .generate-font-size-styles-loop(@fontSizeStart);
}

.generate-font-size-styles();

.ql-tooltip::before {
  content: "查看链接" !important;
}

.ql-tooltip .ql-action::after {
  content: "编辑" !important;
}

.ql-editing .ql-action::after {
  content: "保存" !important;
}
.ql-tooltip .ql-remove::before {
  content: "删除" !important;
}
</style>

<style lang="less" scoped>
.link_url {
  display: flex;
  align-items: center;
  margin: 8px 0 20px 0;
  .ant-input {
    width: 550px;
  }
}
</style>
